package cc.magicjson.design.principles.openclose.thread;

import java.util.function.IntConsumer;

/**
 * {@link}
 *
 * @author <a href="mailto:it_magicjson@163.com">MagicJson</a>
 * @since 1.0.0
 */
public class NumberBySynchronizedPrinter extends BaseNumberPrinter {
	private final int n;
	private int counter = 1;
	private final Object lock = new Object();
	private boolean isTurnZero = true;
	public NumberBySynchronizedPrinter(int n) {
		this.n = n;
	}

	@Override
	public void printZeroNumber(IntConsumer intConsumer) {
		for (int i = 0; i < n; i++) {
			synchronized (lock) {
				while (!isTurnZero) {
					try {
						lock.wait();
					} catch (InterruptedException e) {
						throw new RuntimeException(e);
					}
				}
				intConsumer.accept(0);
				isTurnZero = false;
				lock.notifyAll();
			}
		}

	}

	@Override
	public void printEvenNumber(IntConsumer intConsumer) {

		for (int i = 2; i <= n; i += 2) {
			synchronized (lock) {
				while (isTurnZero || counter % 2 != 0) {
					try {
						lock.wait();
					} catch (InterruptedException e) {
						throw new RuntimeException(e);
					}
				}
				intConsumer.accept(counter);
				counter++;
				isTurnZero = true;
				lock.notifyAll();
			}
		}
	}

	@Override
	public void printOddNumber(IntConsumer intConsumer) {

		for (int i = 1; i <= n; i += 2) {
			synchronized (lock) {
				while (isTurnZero || counter % 2 == 0) {
					try {
						lock.wait();
					} catch (InterruptedException e) {
						throw new RuntimeException(e);
					}
				}
				intConsumer.accept(counter);
				counter++;
				isTurnZero = true;
				lock.notifyAll();
			}
		}
	}
}
